package com.os.sys.controller;

import com.os.sys.common.filter.AuthPower;
import com.os.sys.common.utility.PubClass;
import com.os.sys.common.utility.WebClass;
import com.os.sys.common.utility.XJsonInfo;
import com.os.sys.model.ILoginUser;
import com.os.sys.model.T_SYS_Menu;
import com.os.sys.model.T_SYS_Menu_Power;
import com.os.sys.repository.MenuRepository;
import com.os.sys.repository.Menu_PowerRepository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;

/**
 * Created by Administrator on 2016/12/13.
 */

@RestController
@RequestMapping("/api/sys/menu")
public class MenuController {
    @Resource
    private MenuRepository menuRepository;
    @Resource
    private Menu_PowerRepository menu_powerRepository;
    @Resource
    private PubClass pubClass;

    // 后台菜单维护用到的
    @RequestMapping(value = "/getTreeForAdmin")
    public XJsonInfo getTreeForAdmin() {
        List<T_SYS_Menu> listMenu = (List<T_SYS_Menu>) menuRepository.findAll();
        List<T_SYS_Menu_Power> listMenuPower = (List<T_SYS_Menu_Power>) menu_powerRepository.findAll();

        List<T_SYS_Menu> endList = createTree(listMenu, listMenuPower, "0");
        return new XJsonInfo().setData(endList);
    }

    // 后台角色管理用到的
    @AuthPower(passAuth = true)
    @RequestMapping(value = "/getTreeForUser")
    public XJsonInfo getTreeForUser() {

        List<T_SYS_Menu> listMenu = menuRepository.findByEnable(1);
        List<T_SYS_Menu_Power> listMenuPower = menu_powerRepository.findByUrlIsNotNull();

        List<T_SYS_Menu> endList = createTree(listMenu, listMenuPower, "0");
        return new XJsonInfo().setData(endList);
    }

    // 获得当前登录用户菜单权限
    @AuthPower(passAuth = true)
    @RequestMapping(value = "/getTreeForCurrentUser")
    public XJsonInfo getTreeForCurrentUser() {
        ILoginUser loginUser = pubClass.getLoginUser();
        if (loginUser == null) {
            return new XJsonInfo(false, "无法获得登录用户信息");
        }
        List<String> listUerPower = loginUser.getLoginUserRolesPower();

        List<T_SYS_Menu> listMenu = menuRepository.findByEnable(1);
        List<T_SYS_Menu_Power> listMenuPower = (List<T_SYS_Menu_Power>) menu_powerRepository.findAll();

        List<T_SYS_Menu> endList = createUserTree(listMenu, listMenuPower, listUerPower, "0");
        return new XJsonInfo().setData(endList);
    }

    @Transactional
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public XJsonInfo save(@RequestBody T_SYS_Menu info) {
        if (info.getId() != null && info.getId() > 0) {
            T_SYS_Menu dbInfo = menuRepository.findById(info.getId()).orElse(null);
            if (!Objects.equals(dbInfo.getMenuKey(), info.getMenuKey())) { // 如果修改了key，则所有孩子都要更新parentKey
                List<T_SYS_Menu> listChildren = menuRepository.findByParentKey(dbInfo.getMenuKey());
                listChildren.forEach(q -> q.setParentKey(info.getMenuKey()));

                List<T_SYS_Menu_Power> listChildrenPower = menu_powerRepository.findByMenuKey(dbInfo.getMenuKey());
                listChildrenPower.forEach(q -> q.setMenuKey(info.getMenuKey()));

                menu_powerRepository.saveAll(listChildrenPower);
                menuRepository.saveAll(listChildren);
            }
            menuRepository.save(info);
        } else {
            menuRepository.save(info);
            if (WebClass.requestToInt("autoCreateOpen") == 1) {
                T_SYS_Menu_Power pInfo = new T_SYS_Menu_Power();
                pInfo.setMenuKey(info.getMenuKey());
                pInfo.setPowerKey(info.getMenuKey() + "-open");
                pInfo.setName("浏览");
                menu_powerRepository.save(pInfo);
            }
        }


        return new XJsonInfo();
    }

    @RequestMapping(value = "/remove", method = RequestMethod.DELETE)
    public XJsonInfo remove(Long id) {
        menuRepository.deleteById(id);
        return new XJsonInfo();
    }

    private List<T_SYS_Menu> createTree(List<T_SYS_Menu> dbMenu, List<T_SYS_Menu_Power> dbMenu_Power, String parentKey) {
        List<T_SYS_Menu> childrenList = dbMenu.stream().filter(q -> Objects.equals(q.getParentKey(), parentKey)).sorted(comparing(T_SYS_Menu::getOrderIndex).reversed()).collect(Collectors.toList());
        if (childrenList.size() == 0) {
            return null;
        }

        for (T_SYS_Menu source : childrenList) {
            source.setPower(dbMenu_Power.stream().filter(q -> Objects.equals(q.getMenuKey(), source.getMenuKey())).collect(Collectors.toList()));
            source.setChildren(createTree(dbMenu, dbMenu_Power, source.getMenuKey()));
        }
        return childrenList;
    }


    private List<T_SYS_Menu> createUserTree(List<T_SYS_Menu> dbMenu, List<T_SYS_Menu_Power> dbMenu_Power, List<String> listUerPower, String parentKey) {
        List<T_SYS_Menu> childrenList = dbMenu.stream().filter(q -> Objects.equals(q.getParentKey(), parentKey)).sorted(comparing(T_SYS_Menu::getOrderIndex).reversed()).collect(Collectors.toList());
        if (childrenList == null || childrenList.size() == 0) {
            return null;
        }

        List<T_SYS_Menu> endList = new ArrayList<>();
        for (T_SYS_Menu source : childrenList) {

            // 逐个循环孩子，看看用户是否具有某个孩子的浏览入口权限
            Optional<T_SYS_Menu_Power> opPowerInfo = dbMenu_Power.stream().filter(q ->
                    Objects.equals(q.getMenuKey(), source.getMenuKey()) &&
                            listUerPower.contains(q.getMenuKey() + "-open")).findFirst(); // 权限中包含该节点，并且具有open权限的才可以算是可以看到该页面

            // 检查是否有孩子
            List<T_SYS_Menu> listChildren = createUserTree(dbMenu, dbMenu_Power, listUerPower, source.getMenuKey());

            if (listChildren != null && listChildren.size() > 0) {
                source.setChildren(listChildren);

            }

            if (opPowerInfo.isPresent()) { // 如果具有open权限，则默认具有当前节点的入口
                source.setUri(opPowerInfo.get().getUrl());
                if (listChildren != null && listChildren.size() > 0) {
                    source.setChildren(listChildren);
                    endList.add(source);
                } else {
                    endList.add(source);
                }

            } else {  // 如果不具有open权限，则检查是否具有下级，并且具有下级孩子的open权限
                if (listChildren != null && listChildren.size() > 0) {
                    source.setChildren(listChildren);
                    endList.add(source);
                }
            }
        }
        return endList;
    }
}
